package com.linlin.song.bigwork.web.lisenerAndFilter;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.linlin.song.bigwork.entity.Customer;
import com.linlin.song.bigwork.service.CustomerService;

/**
 * Servlet Filter implementation class IdentityFilter
 */
@WebFilter(dispatcherTypes = {DispatcherType.REQUEST }
					, urlPatterns = { "/*" })
public class IdentityFilter implements Filter {
    private CustomerService userService = new CustomerService();
    /**
     * 不用处理的url，一下这些url都可以忽略登陆状态
     */
    private List<String> ignoreUrl = Arrays.asList(
            "/index",
            "/login", 
            "/logout", 
            "/resources/", 
            "/regist", 
            "/findpassword.jsp",
            "/backend/",
            "/cart/add",
            "find_password"
            );
    
    /**
     * 项目根路径，访问项目根路径也不需要拦截
     */
    private String rootPath;

    
	/**
	 * @see Filter#destroy()
	 */
	public void destroy() { }

	/**
	 * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
	 */
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest)req;
		HttpServletResponse response = (HttpServletResponse)res;
		String uri = request.getRequestURI(); //当前访问的url
	
		Object name = request.getSession().getAttribute("name");//如果不为null说明登陆状态，pass
		if(name != null) {
		    chain.doFilter(request, response);
		    return;
		} else if(uri.equals(this.rootPath)) {
		    response.sendRedirect("index.jsp");
		    return;
		}
		//到这里说明是没登陆，而其访问了需要登陆才能看的页面
		String nameInCookie = this.getCookieValue(request, "name");
		String passwordInCookie = this.getCookieValue(request, "password");
		//虽然当前没登陆的，但是cookie中有登陆信息，则提取登陆信息，处理登陆
		if(nameInCookie != null && passwordInCookie != null){
		    Customer customer = this.userService.check(nameInCookie, passwordInCookie);
		    if(customer != null){
    		    request.getSession().setAttribute("name", nameInCookie); //设置登陆信息
    		    request.getSession().setAttribute("customerId", customer.getId());
    		    ServletContext application = request.getSession().getServletContext();
                AtomicInteger counter = (AtomicInteger)application.getAttribute("counter");
                counter.incrementAndGet();
		    }
        }
		
		for (String ignore : ignoreUrl) {
            if(uri.contains(ignore)) {
                chain.doFilter(request, response); //如果是允许直接通过的url，pass
                return;
            }
        }
		if (nameInCookie == null && passwordInCookie == null) {
            //没登陆，也没有cookie记录登陆信息，则跳转到登陆页面
		    request.getRequestDispatcher("/WEB-INF/view/commons/login_alert.jsp").forward(request, response);
        }
		
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
	    rootPath = fConfig.getServletContext().getContextPath() + "/";
	}
	/**
	 * 从cookie中读取指定的值
	 * @param request
	 * @param key
	 * @return
	 */
	private String getCookieValue(HttpServletRequest request, String key) {
	    Cookie cookies[]=request.getCookies();
	  //遍历cookie
	  if(cookies == null || cookies.length == 0) return null;
	  for(Cookie cookie: cookies){
	      if(cookie.getName().equals(key)){
	          try {
                return URLDecoder.decode(cookie.getValue(), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
	      }
	  }
	  return null;
	} 
}
